<template>
  <div
    v-if="!removeByEmpty || innerData.length > 0"
    ref="grpRef"
    :class="[!loading && innerData.length === 0 && emptyFit ? 'flex flex-col h-full' : '']"
  >
    <div v-if="title" class="pt-4.5 text-color-main font-semibold text-lg"> {{ title }} </div>
    <a-skeleton v-if="loading" active></a-skeleton>
    <div v-else-if="innerData.length === 0" class="flex items-center justify-center flex-1">
      <SlEmpty />
    </div>
    <template v-else>
      <template v-for="item in innerData" :key="item.title">
        <div v-if="item.title !== defaultTitle" class="pt-4.5 font-semibold text-color-main grp-item">
          {{ item.title }}
        </div>
        <div class="flex flex-wrap pt-4.5 -mb-4.5">
          <div
            v-for="(el, i) in item.attrList"
            :key="i"
            class="mb-4.5 w-1/3 grp-item"
            :class="[center ? 'text-center' : '']"
            :style="typeof colNum == 'number' ? { width: (1 / colNum) * 100 + '%' } : {}"
          >
            <div v-if="typeof el.attributeValue === 'boolean'" class="mb-1">
              <span v-if="el.attributeValue" class="text-xl font-semibold text-color-success" :class="textClass">
                ON
              </span>
              <span v-else class="text-xl font-semibold text-color-danger" :class="textClass">OFF</span>
              <!-- <Icon
            :type="el.value ? 'icon-duihao' : 'icon-guanbi'"
            class="text-xl"
            :class="[el.value ? 'text-color-success' : 'text-color-danger']"
          /> -->
            </div>
            <div v-else class="mb-1">
              <span
                class="text-color-main text-2xl font-semibold"
                :class="[
                  textClass,
                  {
                    'text-color-success': el.attributeValue === 'ON',
                    'text-color-danger': el.attributeValue === 'OFF',
                  },
                ]"
              >
                {{ handleValue(el.attributeValue) }}
              </span>
              <span v-if="el.unit" class="text-color-secondary text-xs ml-1" :class="textClass">{{ el.unit }}</span>
            </div>
            <div class="text-color-secondary" :class="textClass">
              <span class="inline-block pr-2" :style="labelStyle">{{ el.attributeName }}</span>
            </div>
          </div>
        </div>
      </template>
    </template>
  </div>
</template>
<script setup lang="ts">
import { computed, CSSProperties, nextTick, shallowRef, watch } from "vue";
import type { EqAttrGroupItem } from "/@/api/aiot/equipment/models";
import { isNullOrUndefOrEmpty, handleValue } from "/@/utils/common";
import { cloneDeep } from "lodash-es";
import { getElRelativeXY, getStyle } from "/@/utils/dom";

const props = withDefaults(
  defineProps<{
    data: EqAttrGroupItem[];
    defaultTitle: string;
    //没有数据时移除
    removeByEmpty?: boolean;
    loading?: boolean;
    colNum?: number | "auto";
    maxNum?: number;
    title?: string;
    textClass?: string;
    center?: boolean;
    more?: boolean;
    labelStyle?: CSSProperties;
    emptyFit?: boolean;
  }>(),
  {
    emptyFit: true,
  }
);
const ATTR_ITEM_MIN_HEIGHT = 80;
const emits = defineEmits(["update:more"]);

const innerData = computed(() => {
  if (!props.data) return [];
  //将默认分组的参数放到第一个位置
  const copyData = cloneDeep(props.data);
  const defaultGroupIndex = copyData.findIndex((el) => el.title === props.defaultTitle);
  if (defaultGroupIndex > -1) {
    const re = copyData.splice(defaultGroupIndex, 1);
    copyData.unshift(re[0]);
  }
  let isEmpty = true;
  //将display为false的属性去掉 并处理属性值
  copyData.forEach((item) => {
    for (let i = item.attrList.length - 1; i >= 0; i--) {
      if (!item.attrList[i].display) {
        item.attrList.splice(i, 1);
      }
    }
    item.attrList.forEach((attr) => {
      isEmpty = false;
      let value = attr.attributeValue;
      if (isNullOrUndefOrEmpty(value)) {
        value = "--";
        attr.unit = "";
      } else if (typeof value !== "boolean") {
        let _value = +value;
        if (_value || _value === 0) {
          value = _value;
        }
      }
      if (attr.dataType === "boolean") {
        if (value === 1 || value === 0) {
          value = !!value;
        }
      }
      attr.attributeValue = value;
    });
  });
  //处理最多显示的属性个数限制
  let more = false;
  if (props.maxNum && !isEmpty) {
    let displayNum = 0;
    for (let i = 0; i < copyData.length; i++) {
      const item = copyData[i];
      const len = item.attrList.length;
      displayNum += len;
      if (displayNum > props.maxNum) {
        more = true;
        const removeNum = displayNum - props.maxNum;
        item.attrList.splice(len - removeNum, removeNum);
        if (item.attrList.length === 0) {
          copyData.splice(i, 1);
        }
        break;
      }
    }
  }
  emits("update:more", more);
  return isEmpty ? [] : copyData;
});
watch(innerData, () => {
  nextTick(() => {
    checkOverParent();
  });
});

const grpRef = shallowRef<HTMLDivElement>();
/**
 * 检测参数生成的dom有没有超过父元素 超过则隐藏 并触发update:more
 * 仅在父元素是相对定位以及overflow为hidden下有效
 */
function checkOverParent() {
  if (grpRef.value) {
    const parent = grpRef.value.parentNode as HTMLElement;
    if (getStyle(parent, "position") === "relative" && getStyle(parent, "overflow") === "hidden") {
      const pH = parent.offsetHeight;
      const items = grpRef.value.querySelectorAll<HTMLDivElement>(".grp-item");
      let more = false;
      for (let i = items.length - 1; i >= 0; i--) {
        const item = items[i];
        const { y } = getElRelativeXY(item, parent);
        let mb = getStyle(item, "margin-bottom", true) as number;
        if (y + item.offsetHeight + mb > pH) {
          item.style.visibility = "hidden";
          more = true;
        } else {
          item.style.visibility = "visible";
        }
      }
      emits("update:more", more);
    }
  }
}
</script>
